home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Personal Computer World 2009 February
/
PCWFEB09.iso
/
Software
/
Linux
/
Kubuntu 8.10
/
kubuntu-8.10-desktop-i386.iso
/
casper
/
filesystem.squashfs
/
etc
/
apparmor
/
rc.apparmor.functions
< prev
next >
Wrap
Text File
|
2008-10-08
|
13KB
|
508 lines
#!/bin/sh
#
# $Id: rc.apparmor.functions 1280 2008-06-09 11:00:28Z jrjohansen $
#
# ----------------------------------------------------------------------
# Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
# NOVELL (All rights reserved)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public
# License published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, contact Novell, Inc.
# ----------------------------------------------------------------------
# rc.apparmor.functions by Steve Beattie
#
# NOTE: rc.apparmor initscripts that source this file need to implement
# the following set of functions:
# aa_action
# aa_log_success_msg
# aa_log_warning_msg
# aa_log_failure_msg
# aa_log_skipped_msg
# Some nice defines that we use
CONFIG_DIR=/etc/apparmor
MODULE=apparmor
OLD_MODULE=subdomain
if [ -f "${CONFIG_DIR}/${MODULE}.conf" ] ; then
APPARMOR_CONF="${CONFIG_DIR}/${MODULE}.conf"
elif [ -f "${CONFIG_DIR}/${OLD_MODULE}.conf" ] ; then
APPARMOR_CONF="${CONFIG_DIR}/${OLD_MODULE}.conf"
elif [ -f "/etc/immunix/subdomain.conf" ] ; then
aa_log_warning_msg "/etc/immunix/subdomain.conf is deprecated, use ${CONFIG_DIR}/subdomain.conf instead"
APPARMOR_CONF="/etc/immunix/subdomain.conf"
elif [ -f "/etc/subdomain.conf" ] ; then
aa_log_warning_msg "/etc/subdomain.conf is deprecated, use ${CONFIG_DIR}/subdomain.conf instead"
APPARMOR_CONF="/etc/subdomain.conf"
else
aa_log_warning_msg "Unable to find config file in ${CONFIG_DIR}, installation problem?"
fi
# Read configuration options from /etc/subdomain.conf, default is to
# warn if subdomain won't load.
SUBDOMAIN_MODULE_PANIC="warn"
SUBDOMAIN_ENABLE_OWLSM="no"
APPARMOR_ENABLE_AAEVENTD="no"
if [ -f "${APPARMOR_CONF}" ] ; then
#parse the conf file to see what we should do
. "${APPARMOR_CONF}"
fi
PARSER=/sbin/apparmor_parser
# SUBDOMAIN_DIR and APPARMOR_DIR might be defined in subdomain.conf|apparmor.conf
if [ -d "${APPARMOR_DIR}" ] ; then
PROFILE_DIR=${APPARMOR_DIR}
elif [ -d "${SUBDOMAIN_DIR}" ] ; then
PROFILE_DIR=${SUBDOMAIN_DIR}
elif [ -d /etc/apparmor.d ] ; then
PROFILE_DIR=/etc/apparmor.d
elif [ -d /etc/subdomain.d ] ; then
PROFILE_DIR=/etc/subdomain.d
fi
ABSTRACTIONS="-I${PROFILE_DIR}"
AA_EV_BIN=/usr/sbin/aa-eventd
AA_EV_PIDFILE=/var/run/aa-eventd.pid
AA_STATUS=/usr/sbin/apparmor_status
SD_EV_BIN=/usr/sbin/sd-event-dispatch.pl
SD_EV_PIDFILE=/var/run/sd-event-dispatch.init.pid
SD_STATUS=/usr/sbin/subdomain_status
SECURITYFS=/sys/kernel/security
SUBDOMAINFS_MOUNTPOINT=$(grep subdomainfs /etc/fstab | \
sed -e 's|^[[:space:]]*[^[:space:]]\+[[:space:]]\+\(/[^[:space:]]*\)[[:space:]]\+subdomainfs.*$|\1|' 2> /dev/null)
if [ -d "/var/lib/${MODULE}" ] ; then
APPARMOR_TMPDIR="/var/lib/${MODULE}"
elif [ -d "/var/lib/${OLD_MODULE}" ] ; then
APPARMOR_TMPDIR="/var/lib/${OLD_MODULE}"
else
APPARMOR_TMPDIR="/tmp"
fi
# keep exit status from parser during profile load. 0 is good, 1 is bad
STATUS=0
# Test if the apparmor "module" is present.
is_apparmor_present() {
local modules=$1
shift
while [ $# -gt 0 ] ; do
modules="$modules|$1"
shift
done
# check for subdomainfs version of module
grep -qE "^($modules)[[:space:]]" /proc/modules
if [ $? -ne 0 ] ; then
ls /sys/module/apparmor 2>/dev/null | grep -qE "^($modules)"
fi
return $?
}
# This set of patterns to skip needs to be kept in sync with
# SubDomain.pm::isSkippableFile()
skip_profile() {
local profile=$1
if [ "${profile%.rpmnew}" != "${profile}" -o \
"${profile%.rpmsave}" != "${profile}" -o \
"${profile%.dpkg-new}" != "${profile}" -o \
"${profile%.dpkg-old}" != "${profile}" -o \
"${profile%.dpkg-dist}" != "${profile}" -o \
-e "${PROFILE_DIR}/disable/`basename ${profile}`" -o \
"${profile%\~}" != "${profile}" ] ; then
return 0
fi
return 1
}
force_complain() {
local profile=$1
# if profile not in complain mode
if ! egrep -q "^/.*[ \t]+flags[ \t]*=[ \t]*\([ \t]*complain[ \t]*\)[ \t]+{" $profile ; then
local link="${PROFILE_DIR}/force-complain/`basename ${profile}`"
if [ -e "$link" ] ; then
echo "Warning: found $link, forcing complain mode"
return 0
fi
fi
return 1
}
parse_profiles() {
# get parser arg
case "$1" in
load)
PARSER_ARGS="--add"
PARSER_MSG="Loading AppArmor profiles "
;;
reload)
PARSER_ARGS="--replace"
PARSER_MSG="Reloading AppArmor profiles "
;;
*)
exit 1
;;
esac
echo -n "$PARSER_MSG"
# run the parser on all of the apparmor profiles
if [ ! -f "$PARSER" ]; then
aa_log_failure_msg "- AppArmor parser not found"
exit 1
fi
if [ ! -d "$PROFILE_DIR" ]; then
aa_log_skipped_msg "- Profile directory not found\nNo AppArmor policy loaded."
return 1
fi
if [ -z "$(ls $PROFILE_DIR/)" ]; then
aa_log_skipped_msg "- No profiles found\nNo AppArmor policy loaded."
return 1
fi
for profile in $PROFILE_DIR/*; do
if skip_profile "${profile}" ; then
echo " Skipping profile $profile"
logger -t "AppArmor(init)" -p daemon.warn "Skipping profile $profile"
STATUS=2
elif [ -f "${profile}" ] ; then
COMPLAIN=""
if force_complain "${profile}" ; then
COMPLAIN="-C"
fi
$PARSER $ABSTRACTIONS $PARSER_ARGS $COMPLAIN "$profile" > /dev/null
if [ $? -ne 0 ]; then
echo " Profile $profile failed to load"
STATUS=1
fi
fi
done
if [ $STATUS -eq 0 ]; then
aa_log_success_msg
elif [ $STATUS -eq 2 ]; then
aa_log_warning_msg
else
aa_log_failure_msg
exit $STATUS
fi
}
profiles_names_list() {
# run the parser on all of the apparmor profiles
TMPFILE=$1
if [ ! -f "$PARSER" ]; then
aa_log_failure_msg "- AppArmor parser not found"
exit 1
fi
if [ ! -d "$PROFILE_DIR" ]; then
aa_log_failure_msg "- Profile directory not found"
exit 1
fi
for profile in $PROFILE_DIR/*; do
if ! skip_profile "${profile}" && [ -f "${profile}" ] ; then
LIST_ADD=$($PARSER $ABSTRACTIONS -N "$profile" | grep -v '\^')
if [ $? -eq 0 ]; then
echo "$LIST_ADD" >>$TMPFILE
fi
fi
done
}
failstop_system() {
level=$(runlevel | cut -d" " -f2)
if [ $level -ne "1" ] ; then
aa_log_failure_msg "- could not start AppArmor. Changing to runlevel 1"
telinit 1;
return -1;
fi
aa_log_failure_msg "- could not start AppArmor."
return -1
}
module_panic() {
# the module failed to load, determine what action should be taken
case "$SUBDOMAIN_MODULE_PANIC" in
"warn"|"WARN")
return 1 ;;
"panic"|"PANIC") failstop_system
rc=$?
return $rc ;;
*) aa_log_failure_msg "- invalid AppArmor module fail option"
return -1 ;;
esac
}
is_apparmor_loaded() {
if ! is_securityfs_mounted ; then
mount_securityfs
fi
mount_subdomainfs
if [ -f "${SECURITYFS}/${MODULE}/profiles" ]; then
SFS_MOUNTPOINT="${SECURITYFS}/${MODULE}"
return 0
fi
if [ -f "${SECURITYFS}/${OLD_MODULE}/profiles" ]; then
SFS_MOUNTPOINT="${SECURITYFS}/${OLD_MODULE}"
return 0
fi
if [ -f "${SUBDOMAINFS_MOUNTPOINT}/profiles" ]; then
SFS_MOUNTPOINT=${SUBDOMAINFS_MOUNTPOINT}
return 0
fi
# check for subdomainfs version of module
is_apparmor_present apparmor subdomain
return $?
}
is_securityfs_mounted() {
grep -q securityfs /proc/filesystems && grep -q securityfs /proc/mounts
return $?
}
mount_securityfs() {
if grep -q securityfs /proc/filesystems ; then
aa_action "Mounting securityfs on ${SECURITYFS}" \
mount -t securityfs securityfs "${SECURITYFS}"
return $?
fi
return 0
}
mount_subdomainfs() {
# for backwords compatibility
if grep -q subdomainfs /proc/filesystems && \
! grep -q subdomainfs /proc/mounts && \
[ -n "${SUBDOMAINFS_MOUNTPOINT}" ]; then
aa_action "Mounting subdomainfs on ${SUBDOMAINFS_MOUNTPOINT}" \
mount "${SUBDOMAINFS_MOUNTPOINT}"
return $?
fi
return 0
}
unmount_subdomainfs() {
SUBDOMAINFS=$(grep subdomainfs /proc/mounts | cut -d" " -f2 2> /dev/null)
if [ -n "${SUBDOMAINFS}" ]; then
aa_action "Unmounting subdomainfs" umount ${SUBDOMAINFS}
fi
}
load_module() {
local rc=0
if modinfo -F filename apparmor > /dev/null 2>&1 ; then
MODULE=apparmor
elif modinfo -F filename ${OLD_MODULE} > /dev/null 2>&1 ; then
MODULE=${OLD_MODULE}
fi
if ! is_apparmor_present apparmor subdomain ; then
aa_action "Loading AppArmor module" /sbin/modprobe -q $MODULE $1
rc=$?
if [ $rc -ne 0 ] ; then
module_panic
rc=$?
if [ $rc -ne 0 ] ; then
exit $rc
fi
fi
fi
if ! is_apparmor_loaded ; then
return 1
fi
return $rc
}
apparmor_start() {
if ! is_apparmor_loaded ; then
load_module
rc=$?
if [ $rc -ne 0 ] ; then
return $rc
fi
fi
if [ ! -w "$SFS_MOUNTPOINT/.load" ] ; then
aa_log_failure_msg "Loading AppArmor profiles - failed, Do you have the correct privileges?"
return 1
fi
configure_owlsm
if [ $(wc -l "$SFS_MOUNTPOINT/profiles" | awk '{print $1}') -eq 0 ] ; then
parse_profiles load
else
aa_log_skipped_msg "Loading AppArmor profiles - AppArmor already loaded with profiles."
fi
}
remove_profiles() {
# removing profiles as we directly read from subdomainfs
# doesn't work, since we are removing entries which screws up
# our position. Lets hope there are never enough profiles to
# overflow the variable
if ! is_apparmor_loaded ; then
aa_log_failure_msg "- failed, is AppArmor loaded?"
return 1
fi
if [ ! -w "$SFS_MOUNTPOINT/.remove" ] ; then
aa_log_failure_msg "- failed, Do you have the correct privileges?"
return 1
fi
if [ ! -x "${PARSER}" ] ; then
aa_log_failure_msg "- failed, unable to execute AppArmor parser"
return 1
fi
retval=0
#the list of profiles isn't stable once we start adding or removing
#them so stor to tmp first
MODULE_PLIST=$(mktemp ${APPARMOR_TMPDIR}/tmp.XXXXXXXX)
sed -e "s/ (\(enforce\|complain\))$//" "$SFS_MOUNTPOINT/profiles" | sort >"$MODULE_PLIST"
cat "$MODULE_PLIST" | while read profile ; do
echo -n "$profile" > "$SFS_MOUNTPOINT/.remove"
rc=$?
if [ ${rc} -ne 0 ] ; then
retval=${rc}
fi
done
rm "$MODULE_PLIST"
if [ ${retval} -eq 0 ] ; then
aa_log_success_msg
else
aa_log_failure_msg
fi
return ${retval}
}
apparmor_stop() {
echo -n "Unloading AppArmor profiles "
remove_profiles
return $?
}
apparmor_kill() {
if ! is_apparmor_loaded ; then
aa_log_failure_msg "Killing AppArmor module - failed, AppArmor is not loaded."
return 1
fi
unmount_subdomainfs
if is_apparmor_present apparmor ; then
MODULE=apparmor
elif is_apparmor_present subdomain ; then
MODULE=subdomain
else
aa_log_failure_msg "Killing AppArmor module - failed, AppArmor is builtin"
return 1
fi
aa_action "Unloading AppArmor modules" /sbin/modprobe -qr $MODULE
return $?
}
__apparmor_restart() {
if [ ! -w "$SFS_MOUNTPOINT/.load" ] ; then
aa_log_failure_msg "Loading AppArmor profiles - failed, Do you have the correct privileges?"
return 4
fi
configure_owlsm
parse_profiles reload
PNAMES_LIST=$(mktemp ${APPARMOR_TMPDIR}/tmp.XXXXXXXX)
profiles_names_list ${PNAMES_LIST}
MODULE_PLIST=$(mktemp ${APPARMOR_TMPDIR}/tmp.XXXXXXXX)
sed -e "s/ (\(enforce\|complain\))$//" "$SFS_MOUNTPOINT/profiles" | sort >"$MODULE_PLIST"
sort "$PNAMES_LIST" | comm -2 -3 "$MODULE_PLIST" - | while read profile ; do
echo -n "$profile" > "$SFS_MOUNTPOINT/.remove"
done
rm "$MODULE_PLIST"
rm "$PNAMES_LIST"
return 0
}
apparmor_restart() {
if ! is_apparmor_loaded ; then
apparmor_start
rc=$?
return $rc
fi
__apparmor_restart
return $?
}
apparmor_try_restart() {
if ! is_apparmor_loaded ; then
return 0
fi
__apparmor_restart
return $?
}
configure_owlsm () {
if [ "${SUBDOMAIN_ENABLE_OWLSM}" = "yes" -a -f ${SFS_MOUNTPOINT}/control/owlsm ] ; then
# Sigh, the "sh -c" is necessary for the SuSE aa_action
# and it can't be abstracted out as a seperate function, as
# that breaks under RedHat's action, which needs a
# binary to invoke.
aa_action "Enabling OWLSM extension" sh -c "echo -n \"1\" > \"${SFS_MOUNTPOINT}/control/owlsm\""
elif [ -f "${SFS_MOUNTPOINT}/control/owlsm" ] ; then
aa_action "Disabling OWLSM extension" sh -c "echo -n \"0\" > \"${SFS_MOUNTPOINT}/control/owlsm\""
fi
}
apparmor_status () {
if test -x ${AA_STATUS} ; then
${AA_STATUS} --verbose
return $?
fi
if test -x ${SD_STATUS} ; then
${SD_STATUS} --verbose
return $?
fi
if ! is_apparmor_present apparmor subdomain ; then
echo "AppArmor is not loaded."
rc=1
else
echo "AppArmor is enabled,"
rc=0
fi
echo "Install the apparmor-utils package to receive more detailed"
echo "status information here (or examine ${SFS_MOUNTPOINT} directly)."
return $rc
}